namespace Runoi.DataBase;

/// <summary>
/// SqlSugar 实体仓储
/// </summary>
/// <typeparam name="T"></typeparam>
public class SqlSugarRepository<T> : SimpleClient<T>, ISqlSugarRepository<T> where T : class, new()
{
    /// <summary>
    /// 构造函数
    /// </summary>
    public SqlSugarRepository()
    {
        var sqlSugarScope = SqlSugarSetup.SqlSugarScope; 
        base.Context = sqlSugarScope.GetConnectionScope(ConstSqlSugar.MainConfigId);

        // 若实体贴有多库特性，则返回指定库连接
        if (typeof(T).IsDefined(typeof(TenantAttribute), false))
        {
            base.Context = sqlSugarScope.GetConnectionScopeWithAttr<T>();
            return;
        }
    }

    #region 分表操作
    /// <summary>
    /// 分表插入
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SplitTableInsertAsync(T input)
    {
        return await base.AsInsertable(input).SplitTable().ExecuteCommandAsync() > 0;
    }
    /// <summary>
    /// 分表批量插入
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SplitTableInsertAsync(List<T> input)
    {
        return await base.AsInsertable(input).SplitTable().ExecuteCommandAsync() > 0;
    }
    /// <summary>
    /// 分表更新
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SplitTableUpdateAsync(T input)
    {
        return await base.AsUpdateable(input).SplitTable().ExecuteCommandAsync() > 0;
    }
    /// <summary>
    /// 分表批量更新
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SplitTableUpdateAsync(List<T> input)
    {
        return await base.AsUpdateable(input).SplitTable().ExecuteCommandAsync() > 0;
    }
    /// <summary>
    /// 分表删除
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SplitTableDeleteableAsync(T input)
    {
        return await base.Context.Deleteable(input).SplitTable().ExecuteCommandAsync() > 0;
    }
    /// <summary>
    /// 分表批量删除
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<bool> SplitTableDeleteableAsync(List<T> input)
    {
        return await base.Context.Deleteable(input).SplitTable().ExecuteCommandAsync() > 0;
    }
    /// <summary>
    /// 分表获取第一条
    /// </summary>
    /// <param name="whereExpression"></param>
    /// <returns></returns>
    public Task<T> SplitTableGetFirstAsync(Expression<Func<T, bool>> whereExpression)
    {
        return base.AsQueryable().SplitTable().FirstAsync(whereExpression);
    }
    /// <summary>
    /// 分表判断是否存在
    /// </summary>
    /// <param name="whereExpression"></param>
    /// <returns></returns>
    public Task<bool> SplitTableIsAnyAsync(Expression<Func<T, bool>> whereExpression)
    {
        return base.Context.Queryable<T>().Where(whereExpression).SplitTable().AnyAsync();
    }
    /// <summary>
    /// 分表获取列表
    /// </summary>
    /// <returns></returns>
    public Task<List<T>> SplitTableGetListAsync()
    {
        return Context.Queryable<T>().SplitTable().ToListAsync();
    }
    /// <summary>
    /// 分表获取列表
    /// </summary>
    /// <param name="whereExpression"></param>
    /// <returns></returns>
    public Task<List<T>> SplitTableGetListAsync(Expression<Func<T, bool>> whereExpression)
    {
        return Context.Queryable<T>().Where(whereExpression).SplitTable().ToListAsync();
    }
    /// <summary>
    /// 分表获取列表
    /// </summary>
    /// <param name="whereExpression"></param>
    /// <param name="tableNames"></param>
    /// <returns></returns>
    public Task<List<T>> SplitTableGetListAsync(Expression<Func<T, bool>> whereExpression, string[] tableNames)
    {
        return Context.Queryable<T>().Where(whereExpression).SplitTable(t => t.InTableNames(tableNames)).ToListAsync();
    }

    #endregion 分表操作

    /// <summary>
    /// 重置表数据
    /// </summary>
    /// <returns></returns>
    public async Task TruncateTable()
    {
        var tableName = typeof(T);
        var config = base.Context.CurrentConnectionConfig;
        if (config.DbType == SqlSugar.DbType.Sqlite)
            await App.GetRequiredService<ISqlSugarClient>().SqlQueryable<T>($"DELETE FROM {tableName.Name}").ToListAsync();
        else
            await App.GetRequiredService<ISqlSugarClient>().SqlQueryable<T>($"truncate table {tableName.Name}").ToListAsync();
    }

}